package com.javacv.plus.extensions.image.steps;

import com.javacv.plus.core.processor.ProcessorContext;
import com.javacv.plus.core.processor.ProcessorStep;
import com.javacv.plus.extensions.image.ImageProcessor;
import com.javacv.plus.extensions.image.ProcessorResult;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_core.Point2f;
import org.bytedeco.opencv.opencv_core.Size;
import org.bytedeco.opencv.global.opencv_imgproc;

/**
 * 图像旋转步骤
 */
@Slf4j
public class RotateStep implements ProcessorStep<ImageProcessor, ProcessorResult> {
    private final double angle;

    public RotateStep(double angle) {
        this.angle = angle;
    }

    @Override
    public ProcessorResult execute(ImageProcessor processor, ProcessorContext context) throws Exception {
        Mat currentImage = context.getAttribute("currentImage");
        if (currentImage == null) {
            throw new IllegalStateException("当前图像为空");
        }

        log.debug("旋转图像，角度: {} 度", angle);

        int width = currentImage.cols();
        int height = currentImage.rows();

        // 计算旋转中心点
        Point2f center = new Point2f(width / 2f, height / 2f);

        // 获取旋转矩阵
        Mat rotationMatrix = opencv_imgproc.getRotationMatrix2D(center, angle, 1.0);

        // 计算旋转后的图像大小
        double cos = Math.abs(rotationMatrix.createIndexer().getDouble(0, 0));
        double sin = Math.abs(rotationMatrix.createIndexer().getDouble(0, 1));

        int newWidth = (int) (height * sin + width * cos);
        int newHeight = (int) (height * cos + width * sin);

        // 调整旋转矩阵的平移部分
        rotationMatrix.createIndexer().putDouble(new long[]{0, 2}, 
            rotationMatrix.createIndexer().getDouble(0, 2) + newWidth / 2.0 - center.x());
        rotationMatrix.createIndexer().putDouble(new long[]{1, 2}, 
            rotationMatrix.createIndexer().getDouble(1, 2) + newHeight / 2.0 - center.y());

        Mat rotatedImage = new Mat();
        Size newSize = new Size(newWidth, newHeight);

        // 执行旋转
        opencv_imgproc.warpAffine(currentImage, rotatedImage, rotationMatrix, newSize);

        context.setAttribute("currentImage", rotatedImage);
        context.setAttribute("processedImage", rotatedImage);

        log.debug("图像旋转完成，新尺寸: {}x{}", newWidth, newHeight);
        return null;
    }

    @Override
    public String getStepName() {
        return "Rotate";
    }

    @Override
    public int getPriority() {
        return 55;
    }
} 